#include <iostream>
#include <vector>
#include <string>
//#include "iostream"
#include<iomanip> 
#include <time.h>
#include "recursion.h"
#include <chrono>
#define setbit(x,y)  (x|=(1<<y)) //let the y bit be 1  
#define twosetbit(x,y,z) (x|=((1<<y)|(1<<z)))
#define clrbit(x,y)  (x&=~(1<<y)) //let the y bit be 0
#define twoclrbit(x,y,z) (x&=~((1<<y)|(1<<z)) )
#define reversebit(x,y)  (x^=(1<<y)) //reverse the y bit
#define getbit(x,y)   ((x) >> (y)&1) //get the y bit number begin with the 0 bit
using namespace std;
struct stack{unsigned long long int NewSequence;
int left;
int right;

};
stack SequenceCalculate[256];
double SequenceEnergy=1000;
unsigned long long int LowEnergySequence;
double BestNotRecursion(unsigned long long int Sequence,int CurrentLeft,int CurrentRight,int CurrentLayer,double CurrentLowEnergy,int SequenceLength){
    int currentleft=CurrentLeft,currentright=CurrentRight,currentlayer=CurrentLayer,sequnecelength=SequenceLength;
      int CurrentStackLocation=1;
    unsigned long long int temp;
    SequenceCalculate[1].NewSequence=Sequence;
    while (CurrentStackLocation!=0)
    {
        
    
    
     if(currentleft>currentright+2){
        currentleft--;
        currentright++;
        currentlayer++;
        temp=SequenceCalculate[CurrentStackLocation].NewSequence;
        SequenceCalculate[CurrentStackLocation].right=currentright;
          SequenceCalculate[CurrentStackLocation].left=currentleft;

        SequenceCalculate[CurrentStackLocation+1].NewSequence=setbit(temp,currentleft);
         SequenceCalculate[CurrentStackLocation+1].right=currentright;
          SequenceCalculate[CurrentStackLocation+1].left=currentleft;

        SequenceCalculate[CurrentStackLocation+2].NewSequence=setbit(temp,currentright);
        SequenceCalculate[CurrentStackLocation+2].right=currentright;
          SequenceCalculate[CurrentStackLocation+2].left=currentleft;

        SequenceCalculate[CurrentStackLocation+3].NewSequence=clrbit(temp,currentleft);
        SequenceCalculate[CurrentStackLocation+3].right=currentright;
          SequenceCalculate[CurrentStackLocation+3].left=currentleft;
        CurrentStackLocation+=3;

     }
     else if(currentleft==currentright+2){
        currentright++;
        currentlayer++;
        temp=SequenceCalculate[CurrentStackLocation].NewSequence;
        SequenceCalculate[CurrentStackLocation].right=currentright;
          SequenceCalculate[CurrentStackLocation].left==currentleft;

        SequenceCalculate[CurrentStackLocation+1].NewSequence=setbit(temp,currentright);
        SequenceCalculate[CurrentStackLocation+1].right=currentright;
          SequenceCalculate[CurrentStackLocation+1].left=currentleft;
        CurrentStackLocation++;
     }
     else{
        double Energy=0;
        int Autocorrelations=0;;
        for(int i=1;i<sequnecelength;i++){
            for(int j=0;j<sequnecelength-i;j++){
                int ii=(getbit(SequenceCalculate[CurrentStackLocation].NewSequence,j));
                int jj=(getbit(SequenceCalculate[CurrentStackLocation].NewSequence,(j+i)));
                 if(/*(ii==1)&&(jj==0)||((ii==0)&&(jj==1))*/ (getbit(SequenceCalculate[CurrentStackLocation].NewSequence,j))^(getbit(SequenceCalculate[CurrentStackLocation].NewSequence,(j+i)))   ){
            Autocorrelations=Autocorrelations-2;
            //Autocorrelations--;
        }
        Autocorrelations++;

            }
            Energy=Energy+Autocorrelations*Autocorrelations;
            Autocorrelations=0;
        }
         Energy=Energy/*-SequenceLength*SequenceLength*/;
       if(Energy<SequenceEnergy){

        //CurrentLowEnergy=Energy;
           SequenceEnergy=Energy;
        LowEnergySequence=SequenceCalculate[CurrentStackLocation].NewSequence;
        

    }
    CurrentStackLocation--;
    currentright=SequenceCalculate[CurrentStackLocation].right;
     currentleft=SequenceCalculate[CurrentStackLocation].left;
}  //else

     

    }//while
    return SequenceEnergy;
}// function

